#!/usr/bin/env bash
#
# Copyright 2023-2025 The Khronos Group Inc.
#
# SPDX-License-Identifier: Apache-2.0

# testBuild - invoke Makefile with the right options to build the test spec
# that is found under build_tests.

# Usage: testBuild

# Fail if any command fails
set -e

# To save bot time and avoid running this script unnecessarily on every
# unrelated change, check for files that have been changed in this branch and
# if they do not affect the build, early out.  This is behind the `--ci` flag
# so local runs always run the tests by default.
is_ci_mode=0
while [ $# -gt 0 ]; do
  case $1 in
    --ci)
      is_ci_mode=1
      shift
      ;;
    *)
      echo "Unrecognized argument $1"
      exit 1
      ;;
  esac
done

# Only early out if --ci.  Assumes a git checkout in this mode.
if [ $is_ci_mode -eq 1 ]; then
  # Look through the list of files changed in this branch
  changed_files=($(git diff --name-only $(git merge-base HEAD origin/main)))
  # And compare against the following allow list.  Every other file is ignored.
  # Notably, the spec text does not affect this test.  vk.xml is also excluded,
  # because it frequently changes, but it very rarely may affect the test
  # results.  Ignoring vk.xml saves significant bot time.
  allowlist=("Makefile" "xml/Makefile" "testBuild" \
    "config/*" "scripts/*" "build_tests/*" \
    "katex/*" "images/*")
  any_match=0

  for file in "${changed_files[@]}"; do
    for allowpattern in "${allowlist[@]}"; do
      if [[ "$file" == $allowpattern ]]; then
        any_match=1
        break
      fi
    done
  done

  if [ $any_match -eq 0 ]; then
    echo "Skipping test as relevant files are unchanged"
    exit 0
  fi
fi

# Build the test spec in various configurations:
function build_spec() {
  build=$1
  options=$2

  echo "-----------------------"
  echo "Building gen-$build ..."

  # Clean existing build, if any
  rm -rf build_tests/gen-$build

  # Note: let options expand, do not quote
  ./makeSpec -spec $options -genpath build_tests/gen-$build -test html

  # Only retain the <body> of the html, so most changes due to asciidoctor changes are not reflected
  # in the test output.  The primary reason for the build tests is to exercise the asciidoctor
  # extensions.
  keepbody='BEGIN { in_body=0 } /<body/ { in_body=1 } /<\/body/ { in_body=0; print} { if (in_body) { print } }'
  htmlpath=build_tests/gen-$build/out/html/
  awk "$keepbody" < $htmlpath/vkspec.html > $htmlpath/vkspec-body.html
}

# Core:
build_spec core "core"
build_spec core-1.0 "core -version 1.0"
# With VK_EXT_host_image_copy
build_spec hic "core -extension VK_EXT_host_image_copy"
build_spec hic-1.0 "core -extension VK_EXT_host_image_copy -version 1.0"
# With VK_KHR_copy_commands2
build_spec copy2-1.0 "core -version 1.0 -extension VK_KHR_copy_commands2"
# All:
build_spec all "all"
build_spec all-1.0 "all -version 1.0"

## Skip VU generation test until new Antora-centric build component interaction is sorted out
## # Test valid usage generation as well
## echo "-----------------------"
## echo "Generating valid usage ..."
## ./makeSpec -spec all -genpath build_tests/gen-validusage -test validusage

echo
echo "======================="

# Verify the results against expectations.  Note: do this after generating all
# builds.  This is to support the build_tests/update-expectations script that
# copies the results over the expectations.
result=0
for build in core core-1.0 hic hic-1.0 copy2-1.0 all all-1.0; do
  echo "Verifying gen-$build is as expected..."
  if ! diff build_tests/expectations/$build.html build_tests/gen-$build/out/html/vkspec-body.html; then
    echo "  FAILED"
    result=1
  fi
done

## Skip VU generation test until new Antora-centric build component interaction is sorted out
## echo "Verifying validusage in gen-validusage is as expected..."
## if ! diff build_tests/expectations/validusage.json build_tests/gen-validusage/out/validation/validusage.json; then
##   echo "  FAILED"
##   result=1
## fi

if [ "$result" -ne 0 ]; then
  echo
  echo "All tests have been built successfully, but the results do not match the"
  echo "expectations."
  echo "If trivial, you can review the diff per the above output."
  echo "Otherwise, please review each failing output at:"
  echo "  - build_tests/gen-*/out/html/vkspec.html, and"
  echo "  - build_tests/gen-validusage/out/validation/validusage.json"
  echo "And ensure they are acceptable.  In that case, update the expectations with:"
  echo "  $ cd build_tests && ./update-expectations"
  exit 1
fi

echo "Success"
